OpenAI DevDayで発表されたJSON形式で返すことが保証される「JSONモード」を、AWS Lambdaを利用して試してみた
はじめに
OpenAI DevDayで発表されたJSONモードをAWS Lambdaを利用して試してみました。
OpenAIの開発者向けカンファレンスのDevDayで様々なアップデートがありました。
弊社ブログでも発表内容がまとめられています。
アップデートのうち、JSON形式でレスポンスを返すことが保証されたJSONモードがサポートされましたので、今回は、新機能をAWS Lambdaを利用して試してみます。
JSONモードに関するドキュメントは、以下のみでコードの例がなかったため、コードも含めて紹介します。
利用するにあたり注意点
- モデルのうち
gpt-4-1106-preview
とgpt-3.5-turbo-1106
のみでJSONモードが利用可能です。 response_format
に{ type:"json_object" }
を設定することで、JSONモードが有効になります。- プロンプトに
JSON
という言葉がない場合、エラーになります。 - レスポンス内容のうち、
finish_reason
がlength
の場合、メッセージが切れている可能性があります。 - JSONモードを使用すると、出力データが正しいJSON形式であることは保証されます。しかし、そのデータが特定のスキーマ(データの構造や形式)に一致するかどうかは保証されません
Lambda
Lambdaで利用するOpenAIアカウントAPIキーの発行方法やOpenAIが提供するPython向けのライブラリをLambdaにアップロードする方法は下記の記事を参考ください。
ランタイムPython 3.11
を選択し、Lambda関数を作成します。
作成後、下記の設定を行います
- 環境変数では、キーはAPI_Key、値はAPIキーの値を入力
- Lambdaのレイヤーを追加します
試してみた
下記のコードで実行してみます。
この例では、1月から12月までの月末の日付(31日、30日など)をグルーピングしてJSON形式で出力しています。
gpt-4-vision-preview
は1日100回までの制限があったため、gpt-3.5-turbo-1106
で検証しました。
from decimal import Decimal import json, os, openai def decimal_to_int(obj): if isinstance(obj, Decimal): return int(obj) def lambda_handler(event, context): openai.api_key = os.environ['API_Key'] input_text = """ 1月から12月のうち、月末の日付(31日、30日など)からグルーピングしてJSON形式で出力してください """ response = openai.ChatCompletion.create( model="gpt-3.5-turbo-1106", messages=[ {"role": "user", "content": input_text} ], response_format= { "type":"json_object" }, temperature=0, ) response_content = response["choices"][0]["message"]["content"] response_content = json.loads(response_content) print("Received response:" + json.dumps(response, default=decimal_to_int, ensure_ascii=False)) return response_content
実行結果は以下の通り、JSONで返ってきました。また、内容も正しいです。
{ "31日": [ "1月", "3月", "5月", "7月", "8月", "10月", "12月" ], "30日": [ "4月", "6月", "9月", "11月" ], "28日または29日": [ "2月" ] }
レスポンス内容は、下記のとおりでした。
finish_reason
がlength
になっている場合は、メッセージが一部切れている可能性があります。
Received response:{ "id": "chatcmpl-8IA9bs4NAl0EVaRugRilyeCnPilSX", "object": "chat.completion", "created": 1699339627, "model": "gpt-3.5-turbo-1106", "choices": [ { "index": 0, "message": { "role": "assistant", "content": "{\n \"31日\": [\"1月\", \"3月\", \"5月\", \"7月\", \"8月\", \"10月\", \"12月\"],\n \"30日\": [\"4月\", \"6月\", \"9月\", \"11月\"],\n \"28日\": [\"2月\"]\n}" }, "finish_reason": "stop" } ], "usage": { "prompt_tokens": 51, "completion_tokens": 65, "total_tokens": 116 }, "system_fingerprint": "fp_eeff13170a" }
エラー
ちなみに、input_text
内にJSONという言葉を削除すると、以下の通り、JSONという言葉をいれましょうと、エラーメッセージが出力されました。
'messages' must contain the word 'json' in some form, to use 'response_format' of type 'json_object'.
他のプロンプト 1
input_text
を下記にしてみます。
input_text = """ 2023年の日本の祝日とその日付を、月ごとにグルーピングしてJSON形式で出力してください。 会社の休みが1月4日と12月4日にあるので、追加してください。 日付を昇順にしてください。 """
レスポンスは下記のとおりです。
天皇誕生日は、令和においては祝日ではないので、間違えていますね。
{ "1月": { "元日": "2023-01-01", "成人の日": "2023-01-09", "会社の休み": "2023-01-04" }, "2月": { "建国記念の日": "2023-02-11" }, "3月": { "春分の日": "2023-03-21" }, "4月": { "昭和の日": "2023-04-29" }, "5月": { "憲法記念日": "2023-05-03", "みどりの日": "2023-05-04", "こどもの日": "2023-05-05" }, "7月": { "海の日": "2023-07-17" }, "8月": { "山の日": "2023-08-11" }, "9月": { "敬老の日": "2023-09-18", "秋分の日": "2023-09-23" }, "10月": { "体育の日": "2023-10-09" }, "11月": { "文化の日": "2023-11-03", "勤労感謝の日": "2023-11-23" }, "12月": { "天皇誕生日": "2023-12-23", "会社の休み": "2023-12-04" } }
他のプロンプト 2
以前、OpenAI API のFunction Callingを利用し、プロンプトの中で、アーティスト名と曲名を抽出し、JSON形式で返すように試したことがあります。
同様のことをJSONモードでもできるか確認します。プロンプトは以下の通りです。
input_text = """ ## 依頼 下記の文章から、アーティスト名と曲名を例を参考にJSON形式で出力して下さい。 アーティスト名や曲名が省略されている場合、正式名称に変換してください。 ## 例 { "artist": "Ado", "song": "うっせいわ" } ## 文章 オフィシャルひげだんディズムのプリテンダーをかけてほしいです。できますか? """
文章からアーティスト名と曲名を抽出することができました。アーティスト名は、正式名称への変換は難しいようですね。
{ "artist": "オフィシャルひげだんディズム", "song": "プリテンダー" }
ちなみに、gpt-3.5-turbo-1106
の場合、Lambdaの実行時間は、3秒程度でした。
終わりに
今回は、DevDayで発表されたJSONモードを試してみました。
JSON形式で返してくれるため、色々な用途で利用できそうですね。色々なプロンプトで試していきたいと思います。
参考になれば幸いです。